package br.com.afi.util.hibernate.validator;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import javax.validation.ConstraintViolation;

/**
 * Essa classe possui o resultado da validação de um objeto.
 * 
 * @author André de Fontana Ignacio
 * @version 1.0
 * @param <T> Objeto validado
 */
public class ValidationResult<T> implements Serializable
{
	private static final long serialVersionUID = 1L;
	private final Set<ConstraintViolation<T>> violations;
	private List<String> invalidMessages;

	/**
	 * Construtor
	 * @param violations Violações
	 */
	protected ValidationResult( Set<ConstraintViolation<T>> violations )
	{
		this.violations = violations;
	}
	
	/**
	 * Obtém as mensagens para os valores inválidos.
	 * 
	 * @return Lista de mensagens.
	 */
	public List<String> getInvalidMessages()
	{
		if( isInvalid() &&  invalidMessages == null )
		{
			buildInvalidMessages();
		}
		return invalidMessages; 
	}

	/**
	 * Adiciona as mensagens inválidas ao StringBuilder informado.
	 * 
	 * @param messageBuilder Mensagens
	 * @param separator Separador
	 * @return Mensagens
	 */
	public StringBuilder buildInvalidMessages( StringBuilder messageBuilder, String separator )
	{
		final StringBuilder sb = new StringBuilder();
		for ( ConstraintViolation<?> invalidValue : violations )
		{
			sb.append( invalidValue.getMessage() ).append( separator );
		}
		if ( sb.length() > 0 )
		{
			messageBuilder.append( sb.toString() );
		}
		return messageBuilder;
	}
	
	/**
	 * Constrói um StringBuilder contendo as mensagens inválidas.
	 * 
	 * @param separator Separador
	 * @return Mensagens
	 */
	public StringBuilder buildInvalidMessages( String separator )
	{
		final StringBuilder messageBuilder = new StringBuilder();
		return buildInvalidMessages( messageBuilder, separator );
	}
	
	/**
	 * Verifica se houve sucesso na validação
	 * 
	 * @return Verdadeiro se houve sucesso na validação
	 */
	public boolean isValid()
	{
		return violations.isEmpty();
	}
	
	/**
	 * Verifica se ocorreu algum problema durante a validação
	 * 
	 * @return Verdadeiro se a validação não foi bem sucedida
	 */
	public boolean isInvalid()
	{
		return !isValid();
	}
	
	/**
	 * Constrói as mensagens para os valores inválidos
	 */
	private void buildInvalidMessages()
	{
		invalidMessages = new ArrayList<String>();
		for ( ConstraintViolation<?> invalidValue : violations )
		{
			invalidMessages.add( invalidValue.getMessage() );
		}
	}
}
